<?php

namespace addons\oss\library;

use addons\oss\traits\FileTrait;
use app\common\model\Attachment;
use Qiniu\Auth;
use Qiniu\Storage\BucketManager;
use Qiniu\Storage\UploadManager;
use think\Config;
use think\Model;

class Qiniu
{

    use FileTrait;

    protected $config = null;

    protected $token = null;

    protected $auth = null;

    public function __construct()
    {
        $this->config = get_addon_config('oss')['qiniu'];
        $this->auth = $auth = new Auth($this->config['accessKeyId'], $this->config['accessKeySecret']);
        $this->token = $auth->uploadToken($this->config['bucket']);
    }

    /**
     * 上传
     * @param null $file
     * @author: Allen Wu
     * @dateTime: 2022/5/15 11:33
     */
    public function upload($file = null)
    {
        if (!$file) return;
        $this->setFile($file);
        $fileInfo = $this->file->getInfo();
        $this->checkSize();
        $this->checkExecutable();
        $this->checkMimetype();
        $this->checkImage();
        $category = request()->post('category');
        $ext = strrchr($this->fileInfo['name'], '.');
        if (!in_array($ext, ['.jpg', '.png', '.jpeg', '.gif', '.mp3', '.mp4']))
            return [];
        $key = 'tools/uploads' . '/' . date('Ymd') . '/' . md5(get_uuid()) . $ext;
        $this->uploadManager = new UploadManager();
        list($ret, $err) = $this->uploadManager->putFile($this->token, $key, $fileInfo['tmp_name']);
        if ($err !== null) {
            throw new \Exception('上传失败');
        } else {
            $auth = \app\common\library\Auth::instance();
            $sha1 = $this->file->hash();
            //添加到附件管理
            return $this->attachment($category, $auth, $ret['key'], $sha1);
        }

    }

    /**
     * 上传远程文件
     * @param $url
     * @param string $ext
     * @author: Allen Wu
     * @dateTime: 2022/5/15 11:34
     */
    public function fetch($url, $ext = '', $isAttachment = true, $category = '')
    {
        $bucketMgr = new BucketManager($this->auth);
        $ext = !$ext ? strrchr($url, '.') : $ext;
        if (!in_array($ext, ['.jpg', '.png', '.jpeg', '.gif', '.mp3', '.mp4']))
            return [];
        $uuid = md5(get_uuid());//uuid
        $key = 'tools/uploads' . '/' . date('Ymd') . '/' . $uuid . $ext;
        [$ret, $err] = $bucketMgr->fetch($url, $this->config['bucket'], $key);
        if (!$err) {
            if ($isAttachment) {
                $auth = \app\common\library\Auth::instance();
                $sha1 = $ret['hash'];
                $this->fileInfo['size'] = $ret['fsize'];
                $this->fileInfo['sha1'] = $ret['hash'];
                $this->fileInfo['name'] = $key;
                $this->fileInfo['type'] = $ret['mimeType'];
                $this->fileInfo['imagewidth'] = 0;
                $this->fileInfo['imageheight'] = 0;
//            $this->fileInfo['imagetype'] = $ext;
                $this->fileInfo['suffix'] = str_replace('.', '', $ext);
                //添加到附件管理
                return $this->attachment($category, $auth, $ret['key'], $sha1);
            } else {
                return ['cdnurl' => cdnurl($key), 'url' => $key];
            }
        }
        throw new \Exception('上传oss失败-' . $url);
    }

    /**
     * 上传字符串到存储
     * @throws \Exception
     * @author: Allen Wu
     * @dateTime: 2022/6/3 21:54
     */
    public function strPut($content, string $ext = '.mp3', string $dir = 'images', bool $is_attachment = true)
    {
        $bucketMgr = new UploadManager();
        $key = $dir . '/' . date('Ymd') . '/' . md5(get_uuid()) . $ext;
        if ($attachment = Attachment::where(['filename' => $key])->find()) {
            return $attachment;
        }
        list($ret, $err) = $bucketMgr->put($this->token, $key, $content);
        if (!$err) {
            if ($is_attachment) {
                $auth = \app\common\library\Auth::instance();
                $sha1 = $ret['hash'];
                $this->fileInfo['size'] = 0;
                $this->fileInfo['sha1'] = $ret['hash'];
                $this->fileInfo['name'] = $key;
                $this->fileInfo['type'] = '';
                $this->fileInfo['imagewidth'] = 0;
                $this->fileInfo['imageheight'] = 0;
//            $this->fileInfo['imagetype'] = $ext;
                $this->fileInfo['suffix'] = str_replace('.', '', '.png');
                //添加到附件管理
                return $this->attachment(0, $auth, $ret['key'], $sha1);
            } else {
                return ['cdnurl' => cdnurl($key, false, true), 'url' => $key];
            }

        }
        return false;
    }

    /**
     * 添加到附件
     * @param $category
     * @param $auth
     * @param $key
     * @param $sha1
     * @return array
     * author: Allen
     * date: 2021/12/22-21:51
     */
    private function attachment($category, $auth, $key, $sha1)
    {

        $params = array(
            'admin_id'    => (int)session('admin.id'),
            'user_id'     => (int)$auth->id,
            'filename'    => mb_substr(htmlspecialchars(strip_tags($key)), 0, 100),//mb_substr(htmlspecialchars(strip_tags($this->fileInfo['name'])), 0, 100),
            'category'    => $category,
            'filesize'    => $this->fileInfo['size'],
            'imagewidth'  => $this->fileInfo['imagewidth'],
            'imageheight' => $this->fileInfo['imageheight'],
            'imagetype'   => $this->fileInfo['suffix'],
            'imageframes' => 0,
            'mimetype'    => $this->fileInfo['type'],
            'url'         => '/' . $key,
            'uploadtime'  => time(),
            'storage'     => 'qiniu',
            'sha1'        => $sha1,
            'extparam'    => '',
        );
        $attachment = new Attachment();
        $attachment->data(array_filter($params));
        $attachment->save();
        return ['url' => '/' . $key, 'cdnurl' => cdnurl('/' . $key, false, true)];
    }

    /**
     * 删除
     * @param $fileName
     * @author: Allen Wu
     * @dateTime: 2022/5/16 20:11
     */
    public function del($fileName)
    {
        $config = new \Qiniu\Config();
        $bucketManager = new \Qiniu\Storage\BucketManager($this->auth, $config);
//        $bucketManager->delete($this->config['bucket'], $fileName);
        $res = $bucketManager->delete($this->config['bucket'], $fileName);
        if ($res[0] == NULL && $res[1] == NULL) {
            return true;
        }
        return false;
    }

    /**
     *
     * @return mixed
     * @author: Allen Wu
     * @dateTime: 2022/5/15 17:02
     */
    public function getAccessKey()
    {
        return $this->config['accessKeyId'];
    }

    /**
     * 访问签名
     * @param $data
     * @return string
     * @author: Allen Wu
     * @dateTime: 2022/5/15 16:10
     */
    public function sign($data)
    {
        $hmac = hash_hmac('sha1', $data, $this->config['accessKeySecret'], true);
        return $this->config['accessKeyId'] . ':' . \Qiniu\base64_urlSafeEncode($hmac);
    }

    public function signWithData($data)
    {
        $encodedData = \Qiniu\base64_urlSafeEncode($data);
        return $this->sign($encodedData) . ':' . $encodedData;
    }


    /**
     * 私有访问url
     * @param $baseUrl
     * @param int $expires
     * @return string
     * @author: Allen Wu
     * @dateTime: 2022/5/15 16:10
     */
    public function privateDownloadUrl($baseUrl, $expires = 60)
    {
//        $baseUrl = $this->config['endpoint'] . $baseUrl;
//        $deadline = time() + $expires;
//        $pos = strpos($baseUrl, '?');
//        if ($pos !== false) {
//            $baseUrl .= '&e=';
//        } else {
//            $baseUrl .= '?e=';
//        }
//        $baseUrl .= $deadline;
//
//        $token = $this->sign($baseUrl);
        return $this->auth->privateDownloadUrl($baseUrl,$expires);
//        return "$baseUrl&token=$token";
    }


}
